#include "socket.hpp"
#include <memory>
#include "Protocol.hpp"
#include <ctime>
#include <unistd.h>
#include <cmath>
#include <thread>
using namespace Protocol;
int main(int argc,char* argv[])
{
    if(argc != 3)
    {
        std::cout<<"Usage ./"<<argv[0]<<" server_ip  server_port\n";
        return 0; 
    }
    uint16_t server_port = std::stoi(argv[2]);
    std::string server_ip = argv[1];

    std::shared_ptr<Net_TcpSocket:: Socket> connectSock (new Net_TcpSocket:: TcpSocket);
    connectSock->CreatSocketOrDie();
    if(!connectSock->ConnectServer(server_ip,server_port))
    {
        std::cout<<"connection failed\n";
        exit(-1);
    }
    std::cout<<"connection success\n";
    
    std::unique_ptr<Factory> factory = std::make_unique<Factory>();

    srand(time(nullptr)^getpid());
    const std::string opers = "+-*/^";


    std::function<void()> RecvInfor= [&connectSock,&factory]()
        {   
            //读取服务的响应的结果
            std::string respStr;
            while(1)
            {
                connectSock->Recv(&respStr,1024);
                std::cout<<"recv Success\n";
                //去掉报头，也就是解码
                std::string msg;
                if(!Decode(respStr,&msg)) 
                    continue;

                //反序列化解析出需要的结果
                auto resp = factory->BuildReponse();
                resp->DeSerialisze(msg);
                
                //计算结果就存储在resp里面
                std::cout<<"Result:"<<resp->GetResult()<<" || Code :"<<resp->GetCode()<<std::endl;
            }
        };

    std::thread td(RecvInfor);
    td.detach();

    while(true)
    {
        double x = rand()%10;
        usleep(rand()%39412);
        double y = rand()%10;
        usleep(rand()%3942);
        int opSub = rand()%opers.size();
        std::shared_ptr<Request> req = factory->BuildRequest(x,y,opers[opSub]);

        //对请求序列化
        std::string requestStr;
        req->Serialisze(&requestStr);

        std::string DebugStr = requestStr;
        std::cout<<DebugStr<<"序列化字符串\n";
        //添加报头，也就是编码
        requestStr =  Encode(requestStr);

        //发送请求
        connectSock->Send(requestStr);
        sleep(100);
        
    }
    return 0;
}